/**
 * Copyright (c) 2012-2016, www.tinygroup.org (luo_guo@icloud.com).
 * <p>
 * Licensed under the GPL, Version 3.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.gnu.org/licenses/gpl.html
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.tinygroup.database.initdata.impl;

import org.tinygroup.commons.tools.StringUtil;
import org.tinygroup.database.config.initdata.InitData;
import org.tinygroup.database.config.initdata.Record;
import org.tinygroup.database.config.initdata.ValuePair;
import org.tinygroup.database.config.table.Table;
import org.tinygroup.database.config.table.TableField;
import org.tinygroup.database.initdata.InitDataSqlProcessor;
import org.tinygroup.database.util.DataBaseUtil;
import org.tinygroup.logger.LogLevel;
import org.tinygroup.logger.Logger;
import org.tinygroup.logger.LoggerFactory;
import org.tinygroup.metadata.config.stdfield.StandardField;
import org.tinygroup.metadata.util.MetadataUtil;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public class InitDataSqlProcessorImpl implements InitDataSqlProcessor {
    private Logger logger = LoggerFactory
            .getLogger(InitDataSqlProcessorImpl.class);

    public List<String> getInitSql(InitData initData) {
        List<String> initSqlList = new ArrayList<String>();
        Table table = DataBaseUtil.getTableById(initData.getTableId(), this
                .getClass().getClassLoader());
        if (initData.getRecordList() != null) {
            for (Record record : initData.getRecordList()) {
                String sql = valuePairsToAddString(record, table);
                if ("".equals(sql)) {
                    continue;
                }
                logger.logMessage(LogLevel.DEBUG, "添加sql:{0}", sql);
                if (!initSqlList.contains(sql)) {
                    initSqlList.add(sql);
                }

            }
        }
        return initSqlList;
    }

    private String valuePairsToAddString(Record record, Table table) {
        List<ValuePair> valuePairs = record.getValuePairs();
        List<String> autoIncreaseField = new ArrayList<String>();
        for(TableField tableField:table.getFieldList()){
            if(tableField.isAutoIncrease()) {
                autoIncreaseField.add(tableField.getId());
            }
        }
        if (valuePairs == null || valuePairs.size() == 0) {
            return "";
        } else {
            StringBuffer keys = new StringBuffer();
            StringBuffer values = new StringBuffer();
            for (ValuePair valuePair : valuePairs) {
                //值为空
                if(StringUtil.isBlank(valuePair.getValue())){
                    continue;
                }
                StandardField standField = DataBaseUtil.getStandardField(
                        valuePair.getTableFieldId(), table, this.getClass()
                                .getClassLoader());
                String standFieldName = DataBaseUtil.getDataBaseName(standField
                        .getName());

                String value = valuePair.getValue();
                // 数据由用户手动填写，包括如''之类的信息
                keys = keys.append(",").append(standFieldName);
                values = values.append(",").append(value);
            }
            //没有字段则不插入
            if(keys.length()==0){
                return "";
            }
            return String.format("INSERT INTO %s (%s) VALUES (%s)",
                    table.getNameWithOutSchema(), keys.substring(1), values.substring(1));
        }
    }

    public List<String> getDeInitSql(InitData initData) {
        List<String> initSqlList = new ArrayList<String>();
        Table table = DataBaseUtil.getTableById(initData.getTableId(), this
                .getClass().getClassLoader());
        List<String> keys = new ArrayList<String>();
        for (TableField field : table.getFieldList()) {
            if (field.getPrimary()) {
                StandardField stdField = MetadataUtil
                        .getStandardField(field.getStandardFieldId(), this
                                .getClass().getClassLoader());
                keys.add(DataBaseUtil.getDataBaseName(stdField.getName())

                );
            }
        }
        if (initData.getRecordList() != null) {
            for (Record record : initData.getRecordList()) {
                String sql = valuePairsToDelString(record, table, keys);
                if ("".equals(sql)) {
                    continue;
                }
                logger.logMessage(LogLevel.DEBUG, "添加sql:{0}", sql);
                if (!initSqlList.contains(sql)) {
                    initSqlList.add(sql);
                }
            }
        }
        return initSqlList;
    }

    public List<String> getPreInitSql(Table table) {
        return new ArrayList<String>();
    }

    public List<String> getPostInitSql(Table table) throws SQLException {
        return new ArrayList<String>();
    }

    private String valuePairsToDelString(Record record, Table table,
                                         List<String> keys) {
        List<ValuePair> valuePairs = record.getValuePairs();
        if (valuePairs == null || valuePairs.size() == 0) {
            return "";
        }

        String where = "";
        int times = 0;// 当单条数据的delete语句生成时,times的次数应该等于keys，即主键列表的长度
        for (ValuePair valuePair : valuePairs) {
            StandardField standField = DataBaseUtil
                    .getStandardField(valuePair.getTableFieldId(), table, this
                            .getClass().getClassLoader());

            String standFieldName = DataBaseUtil.getDataBaseName(standField
                    .getName());
            String value = valuePair.getValue();
            if (!keys.contains(standFieldName)) {
                continue;// 不是主键
            }
            if(StringUtil.isBlank(value)){
                //主键也为空直接跳过
                continue;
            }
            // 数据由用户手动填写，包括如''之类的信息
            where = where
                    + String.format(" AND %s=%s", standFieldName, value);
            times++;
        }
        if (times != keys.size()) {
            /*logger.logMessage(LogLevel.WARN,
                    "不生成删除语句。原因:解析生成delete语句时主键数不匹配,应有主键数{0},实际{1}", keys.size(), times);
*/
            return "";
        }
        int index = where.indexOf("AND");
        where = where.substring(index + 3);
        if(StringUtil.isBlank(where)){
            return "";
        }
        logger.logMessage(LogLevel.WARN,
                "表{0}因设置主键值而生成delete语句",table.getName());
        return String.format("DELETE FROM %s WHERE %s ", table.getNameWithOutSchema(), where);
    }

}
